﻿using System;
using System.IdentityModel.Selectors;
using Cesave.Infrastructure.CrossCutting.IoC;
using Cesave.Domain.PermisosModule.Contracts.Agentes;
using Cesave.Infrastructure.CrossCutting.Hashing;
using Cesave.Domain.PermisosModule.Entities;

namespace Cesave.DistributedServices.PermisosModule
{
	/// <summary>
	/// 
	/// </summary>
    public class PermisosModuleValidator
        : UserNamePasswordValidator
    {

        #region Private properties

		/// <summary>
		/// 
		/// </summary>
		private readonly IAgenteService _agenteService;

		/// <summary>
		/// 
		/// </summary>
        private AuthenticationResult _authenticationResult;

        #endregion

        #region Public properties

		/// <summary>
		/// 
		/// </summary>
        public AuthenticationResult AuthenticationResult
        {
            get
            {
                return _authenticationResult;
            }
        }

        #endregion

        #region Constructors

		/// <summary>
		/// 
		/// </summary>
        public PermisosModuleValidator()
        {
			_agenteService = IoCFactory.Resolve<IAgenteService>();
        }

        #endregion

        #region userNamePasswordValidator overrides

        /// <summary>
        /// <see cref="System.IdentityModel.Selectors.UserNamePasswordValidator"/>
        /// </summary>
        /// <param name="userName">
        /// <see cref="System.IdentityModel.Selectors.UserNamePasswordValidator"/>
        /// </param>
        /// <param name="password">
        /// <see cref="System.IdentityModel.Selectors.UserNamePasswordValidator"/>
        /// </param>
        public override void Validate(string userName, string password)
        {
            try
            {
				Agente agente;
				if (null == (agente = _agenteService.FindAgenteByUsuario(userName)))
				{
					_authenticationResult = AuthenticationResult.UserNotFound;
					throw new AuthenticationException(AuthenticationResult.UserNotFound);
				}
				string storedHash = agente.PasswordHash;
				string userHash = SaltAndHash.Hash(password, agente.PasswordSalt);
				bool passwordsMatch = SaltAndHash.HashCompare(storedHash, userHash);
				if (!passwordsMatch)
				{
					_authenticationResult = AuthenticationResult.WrongPassword;
					throw new AuthenticationException(AuthenticationResult.WrongPassword);
				}
				_authenticationResult = AuthenticationResult.LoginSuccessfull;
            }
            catch (AuthenticationException ex)
            {
                _authenticationResult = AuthenticationResult.LoginFailed;
				throw ex;
            }
        }

        #endregion

    }
}
